/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xml.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import xml.dao.AccountDAO;
import xml.entity.Account;
import xml.entity.Job;
import xml.entity.Jobs;
import org.w3c.dom.Element;
import xml.entity.Jobseeker;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.fop.apps.Driver;
import org.apache.fop.apps.FOPException;
import org.xml.sax.InputSource;

/**
 *
 * @author Kyros
 */
public class SupportUtil {

    public void transform(String xmlURL, String xslURL,
            String foURL) {
        try {
            TransformerFactory tff = TransformerFactory.newInstance();
            StreamSource xmlFile = new StreamSource(xmlURL);
            StreamSource xslFile = new StreamSource(xslURL);
            Transformer tf = tff.newTransformer(xslFile);
            StreamResult htmlFile = new StreamResult(
                    new FileOutputStream(foURL));
            tf.transform(xmlFile, htmlFile);
        } catch (TransformerException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
    }

    public void marshal(String xmlURL, Object obj) {
        try {
            JAXBContext ctx = JAXBContext.newInstance(obj.getClass());
            Marshaller mar = ctx.createMarshaller();
            mar.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
            mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            mar.marshal(obj, new File(xmlURL));
//            mar.marshal(obj, System.out);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public Object unmarshal(String packageName, String urlFile) {
        try {
            JAXBContext jc = JAXBContext.newInstance(packageName);
            Unmarshaller u = jc.createUnmarshaller();
            File f = new File(urlFile);
            Object item = (Object) u.unmarshal(f);
            return item;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean isNull(Object obj) {
        if (obj != null) {
            if (obj instanceof String) {
                if (obj.toString().trim().equals("")) {
                    return true;
                } else {
                    return false;
                }
            } else if (obj instanceof Integer) {
                if (Integer.parseInt(obj.toString()) == 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }

    public Account authenticate(String username, String password) throws SQLException, Exception {
        AccountDAO accountDao = new AccountDAO();
        List<Account> accountList = accountDao.getAllAccount();
        if (username == null || username.equals("")
                || password == null || password.equals("")) {
            return null;
        } else if (accountList != null) {
            for (int i = 0; i < accountList.size(); i++) {
                if (username.equals(accountList.get(i).getUserName())
                        && password.equals(accountList.get(i).getPassword())) {
                    return accountList.get(i);
                }
            }
        }
        return null;
    }

//    public Jobs viewJobOffers(Document doc) throws XPathExpressionException {
//        XPath xpath = XPathFactory.newInstance().newXPath();
//        XPathExpression expr = xpath.compile("//job/*/text()");
//
//        Object result = expr.evaluate(doc, XPathConstants.NODESET);
//        NodeList nodes = (NodeList) result;
//        Jobs jobs = new Jobs();
//        Job job;
//
//        for (int i = 0; i < nodes.getLength(); i++) {
//            job = new Job();
//            job.setJobId(Integer.parseInt(nodes.item(i).getNodeValue()));
//            job.setEmployerId(Integer.parseInt(nodes.item(i + 1).getNodeValue()));
//            job.setEmployeeId(Integer.parseInt(nodes.item(i + 2).getNodeValue()));
//            job.setJobName(nodes.item(i + 3).getNodeValue());
//            job.setJobDesc(nodes.item(i + 4).getNodeValue());
//            job.setCareer(nodes.item(i + 5).getNodeValue());
//            job.setJobType(Short.parseShort(nodes.item(i + 6).getNodeValue()));
//            job.setNeededPos(nodes.item(i + 7).getNodeValue());
//            job.setCity(nodes.item(i + 8).getNodeValue());
//            job.setJobLimit(Integer.parseInt(nodes.item(i + 9).getNodeValue()));
//            job.setSalaryOffer(nodes.item(i + 10).getNodeValue());
//            job.setJobBenefit(nodes.item(i + 11).getNodeValue());
//            job.setRequiredExp(nodes.item(i + 12).getNodeValue());
//            job.setRequiredEdu(nodes.item(i + 13).getNodeValue());
//            job.setOtherRequire(nodes.item(i + 14).getNodeValue());
//            job.setDayOfProfileDealine(Integer.parseInt(nodes.item(i + 15).getNodeValue()));
//            job.setMonthOfProfileDealine(Integer.parseInt(nodes.item(i + 16).getNodeValue()));
//            job.setYearOfProfileDeadline(Integer.parseInt(nodes.item(i + 17).getNodeValue()));
//            job.setProfileRequire(nodes.item(i + 18).getNodeValue());
//            jobs.getJob().add(job);
//        }
//        return jobs;
//    }
    public void editJobOffersXML(Document doc, Job job, int jobId, String xmlPath) throws XPathExpressionException {
        XPath xpath = XPathFactory.newInstance().newXPath();
        // XPath Query for showing all nodes value
        XPathExpression expr = xpath.compile("//job[jobId=" + jobId + "]/*");

        Object result = expr.evaluate(doc, XPathConstants.NODESET);
        NodeList nodes = (NodeList) result;
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if ((node.getNodeName()).equals("jobName")) {
                node.setTextContent(job.getJobName());
            }
            if ((node.getNodeName()).equals("jobDesc")) {
                node.setTextContent(job.getJobDesc());
            }
            if ((node.getNodeName()).equals("career")) {
                node.setTextContent(job.getCareer());
            }
            if ((node.getNodeName()).equals("jobType")) {
                node.setTextContent(String.valueOf(job.getJobType()));
            }
            if ((node.getNodeName()).equals("neededPos")) {
                node.setTextContent(job.getNeededPos());
            }
            if ((node.getNodeName()).equals("city")) {
                node.setTextContent(job.getCity());
            }
            if ((node.getNodeName()).equals("jobLimit")) {
                node.setTextContent(String.valueOf(job.getJobLimit()));
            }
            if ((node.getNodeName()).equals("salaryOffer")) {
                node.setTextContent(job.getSalaryOffer());
            }
            if ((node.getNodeName()).equals("jobBenefit")) {
                node.setTextContent(job.getJobBenefit());
            }
            if ((node.getNodeName()).equals("requiredExp")) {
                node.setTextContent(job.getRequiredExp());
            }
            if ((node.getNodeName()).equals("requiredEdu")) {
                node.setTextContent(job.getRequiredEdu());
            }
            if ((node.getNodeName()).equals("otherRequire")) {
                node.setTextContent(job.getOtherRequire());
            }
            if ((node.getNodeName()).equals("dayOfProfileDealine")) {
                node.setTextContent(String.valueOf(job.getDayOfProfileDealine()));
            }
            if ((node.getNodeName()).equals("monthOfProfileDealine")) {
                node.setTextContent(String.valueOf(job.getMonthOfProfileDealine()));
            }
            if ((node.getNodeName()).equals("yearOfProfileDeadline")) {
                node.setTextContent(String.valueOf(job.getYearOfProfileDeadline()));
            }
            if ((node.getNodeName()).equals("profileRequire")) {
                node.setTextContent(job.getProfileRequire());
            }
        }
        writeXML(doc, xmlPath);
    }

    public void deleteJobOffersXML(Document doc, int jobId, String xmlPath) throws XPathExpressionException {
        XPath xpath = XPathFactory.newInstance().newXPath();
        // XPath Query for showing all nodes value

        XPathExpression expr = xpath.compile("//job[jobId=" + jobId + "]/*");

        Object result = expr.evaluate(doc, XPathConstants.NODESET);
        NodeList nodes = (NodeList) result;
//        Node nodeJob = nodeJobs.item(0);
//        NodeList nodes = nodeJob.getChildNodes();
//        for (int i = 0; i < nodes.getLength(); i++) {
//        System.out.println(nodes.item(2).getNodeValue());
//        }
//        Jobs jobs = new Jobs();
//        int i=0;
        Node nodeJob = nodes.item(0).getParentNode();
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            node.getParentNode().removeChild(node);
//            nodeJob.removeChild(node);
        }
        nodeJob.getParentNode().removeChild(nodeJob);
//        doc.removeChild(nodeJob);
        writeXML(doc, xmlPath);
    }
    
//    public void deleteFileXML(Document doc, String xmlPath) throws XPathExpressionException {
//        XPath xpath = XPathFactory.newInstance().newXPath();
//        // XPath Query for showing all nodes value
//
//        XPathExpression expr = xpath.compile("//job/*");
//
//        Object result = expr.evaluate(doc, XPathConstants.NODESET);
//        NodeList nodes = (NodeList) result;
//        if (nodes == null){
//            File fd = new File(xmlPath);
//            fd.delete();
//        }
//    }

    public void addJobOffersXML(Document doc, Job job, String xmlPath) throws XPathExpressionException {
//        XPath xpath = XPathFactory.newInstance().newXPath();
//        // XPath Query for showing all nodes value
//
//        XPathExpression expr = xpath.compile("//jobs/*");
//
//        Object result = expr.evaluate(doc, XPathConstants.NODESET);
//        NodeList nodes = (NodeList) result;
//        Node nodeJob = nodeJobs.item(0);
//        NodeList nodes = nodeJob.getChildNodes();
//        Node nodeJob = nodes.item(0).getParentNode();
//        for (int i = 0; i < nodes.getLength(); i++) {
//            Node node = nodes.item(i);
//            node.getParentNode().removeChild(node);
//            nodeJob.removeChild(node);
//        }
//        nodeJob.getParentNode().removeChild(nodeJob);
//        doc.removeChild(nodeJob);
        Node nodeJobs = doc.getElementsByTagName("jobs").item(0);
        Element eJob = doc.createElement("job");
        nodeJobs.appendChild(eJob);
        Element eJobId = doc.createElement("jobId");
        eJobId.appendChild(doc.createTextNode(String.valueOf(job.getJobId())));
        eJob.appendChild(eJobId);
        Element eEmployerId = doc.createElement("employerId");
        eEmployerId.appendChild(doc.createTextNode(String.valueOf(job.getEmployerId())));
        eJob.appendChild(eEmployerId);
        Element eEmployeeId = doc.createElement("employeeId");
        eEmployeeId.appendChild(doc.createTextNode(String.valueOf(job.getEmployeeId())));
        eJob.appendChild(eEmployeeId);
        Element eJobName = doc.createElement("jobName");
        eJobName.appendChild(doc.createTextNode(job.getJobName()));
        eJob.appendChild(eJobName);
        Element eJobDesc = doc.createElement("jobDesc");
        eJobDesc.appendChild(doc.createTextNode(job.getJobDesc()));
        eJob.appendChild(eJobDesc);
        Element eCareer = doc.createElement("career");
        eCareer.appendChild(doc.createTextNode(job.getCareer()));
        eJob.appendChild(eCareer);
        Element eJobType = doc.createElement("jobType");
        eJobType.appendChild(doc.createTextNode(String.valueOf(job.getJobType())));
        eJob.appendChild(eJobType);
        Element eNeededPos = doc.createElement("neededPos");
        eNeededPos.appendChild(doc.createTextNode(job.getNeededPos()));
        eJob.appendChild(eNeededPos);
        Element eCity = doc.createElement("city");
        eCity.appendChild(doc.createTextNode(job.getCity()));
        eJob.appendChild(eCity);
        Element eJobLimit = doc.createElement("jobLimit");
        eJobLimit.appendChild(doc.createTextNode(String.valueOf(job.getJobLimit())));
        eJob.appendChild(eJobLimit);
        Element eSalaryOffer = doc.createElement("salaryOffer");
        eSalaryOffer.appendChild(doc.createTextNode(job.getSalaryOffer()));
        eJob.appendChild(eSalaryOffer);
        Element eJobBenefit = doc.createElement("jobBenefit");
        eJobBenefit.appendChild(doc.createTextNode(job.getJobBenefit()));
        eJob.appendChild(eJobBenefit);
        Element eRequiredExp = doc.createElement("requiredExp");
        eRequiredExp.appendChild(doc.createTextNode(job.getRequiredExp()));
        eJob.appendChild(eRequiredExp);
        Element eRequiredEdu = doc.createElement("requiredEdu");
        eRequiredEdu.appendChild(doc.createTextNode(job.getRequiredEdu()));
        eJob.appendChild(eRequiredEdu);
        Element eOtherRequire = doc.createElement("otherRequire");
        eOtherRequire.appendChild(doc.createTextNode(job.getOtherRequire()));
        eJob.appendChild(eOtherRequire);
        Element eDay = doc.createElement("dayOfProfileDealine");
        eDay.appendChild(doc.createTextNode(String.valueOf(job.getDayOfProfileDealine())));
        eJob.appendChild(eDay);
        Element eMonth = doc.createElement("monthOfProfileDealine");
        eMonth.appendChild(doc.createTextNode(String.valueOf(job.getMonthOfProfileDealine())));
        eJob.appendChild(eMonth);
        Element eYear = doc.createElement("yearOfProfileDeadline");
        eYear.appendChild(doc.createTextNode(String.valueOf(job.getYearOfProfileDeadline())));
        eJob.appendChild(eYear);
        Element eProfileRequire = doc.createElement("profileRequire");
        eProfileRequire.appendChild(doc.createTextNode(job.getProfileRequire()));
        eJob.appendChild(eProfileRequire);
        writeXML(doc, xmlPath);
    }

    public static void writeXML(Document doc, String path) {
        try {
            TransformerFactory tff = TransformerFactory.newInstance();
            Transformer tf = tff.newTransformer();
            tf.setOutputProperty("indent", "yes");
            Source source = new DOMSource(doc);
            Result result = new StreamResult(new FileOutputStream(path));
//            System.out.println(result);
            tf.transform(source, result);
            tf.reset();
        } catch (TransformerConfigurationException ex) {
            ex.printStackTrace();
        } catch (TransformerException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Jobs searchJobOffersXML(Document doc, String searchName, String searchCareer, String searchCity) throws XPathExpressionException {
        XPath xpath = XPathFactory.newInstance().newXPath();
        // XPath Query for showing all nodes value

        XPathExpression expr = xpath.compile("//job[./jobName[contains(.,'"+searchName+"')] and ./career[contains(.,'"+searchCareer+"')] and ./city[contains(.,'"+searchCity+"')]]/*/text()");

        Object result = expr.evaluate(doc, XPathConstants.NODESET);
        NodeList nodes = (NodeList) result;
        Jobs jobs = new Jobs();
        Job job;

        for (int i = 0; i < nodes.getLength(); i++) {
            job = new Job();
            job.setJobId(Integer.parseInt(nodes.item(i).getNodeValue()));
            job.setEmployerId(Integer.parseInt(nodes.item(i + 1).getNodeValue()));
            job.setEmployeeId(Integer.parseInt(nodes.item(i + 2).getNodeValue()));
            job.setJobName(nodes.item(i + 3).getNodeValue());
            job.setJobDesc(nodes.item(i + 4).getNodeValue());
            job.setCareer(nodes.item(i + 5).getNodeValue());
            job.setJobType(Short.parseShort(nodes.item(i + 6).getNodeValue()));
            job.setNeededPos(nodes.item(i + 7).getNodeValue());
            job.setCity(nodes.item(i + 8).getNodeValue());
            job.setJobLimit(Integer.parseInt(nodes.item(i + 9).getNodeValue()));
            job.setSalaryOffer(nodes.item(i + 10).getNodeValue());
            job.setJobBenefit(nodes.item(i + 11).getNodeValue());
            job.setRequiredExp(nodes.item(i + 12).getNodeValue());
            job.setRequiredEdu(nodes.item(i + 13).getNodeValue());
            job.setOtherRequire(nodes.item(i + 14).getNodeValue());
            job.setDayOfProfileDealine(Integer.parseInt(nodes.item(i + 15).getNodeValue()));
            job.setMonthOfProfileDealine(Integer.parseInt(nodes.item(i + 16).getNodeValue()));
            job.setYearOfProfileDeadline(Integer.parseInt(nodes.item(i + 17).getNodeValue()));
            job.setProfileRequire(nodes.item(i + 18).getNodeValue());
            jobs.getJob().add(job);
            i = i +18;
        }
        return jobs;
    }

    public void exportPDF(String foURL, String pdfURL) {
        InputStream input = null;
        try {
            Driver driver = new Driver();
            Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
            driver.setLogger(logger);
            org.apache.fop.messaging.MessageHandler.setScreenLogger(logger);
            driver.setRenderer(Driver.RENDER_PDF);
            File xslFOFile = new File(foURL);
            File pdfFile = new File(pdfURL);
            input = new FileInputStream(xslFOFile);
            driver.setInputSource(new InputSource(input));
            OutputStream output = new FileOutputStream(pdfFile);
            driver.setOutputStream(output);
            driver.run();
            output.flush();
            output.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (FOPException ex) {
            ex.printStackTrace();
        }

    }

}
